<template>
	<view class="container">
		<view class="page-body">
			<uni-section title="上传封面" type="line">
				<view class="input-article-photo">
					<uni-file-picker limit="1" title="选择1张图片" @select="selectPhoto" ></uni-file-picker>
				</view>
			</uni-section>
			<uni-section title="文章标题" type="line">
				<view class="input-article-title">
					<uni-easyinput  placeholder="请输入文章标题" @change="articleTitleChange" v-model="articleSaveParam.title"></uni-easyinput>
				</view>
			</uni-section>
			<uni-section title="文章类型" type="line">
				<view class="input-article-category">
					<picker @change="bindPickerChange" :value="index" :range="categoryArray">
						<view class="uni-input">{{categoryArray[index]}}</view>
					</picker>
				</view>
			</uni-section>
			<uni-section title="文章标签" type="line">
				<checkbox-group @change="checkboxChange" class="tag-list">
					<label v-for="item in articleTag" :key="item.id">
						<view class="tag-list-item">
							<checkbox :value="item.id" :checked="item.checked">
								<view>{{item.tagName}}</view>
							</checkbox>
						</view>
					</label>
				</checkbox-group>
			</uni-section>
			<uni-section title="文章设置" type="line">
				<view class="setting-list">
					<view class="setting-item">
						<view class="setting-switch">是否公开</view>
						<switch checked @change="isPublicChange" />
					</view>
					<view class="setting-item">
						<view class="setting-switch">是否收费</view>
						<switch @change="isChargeChange"/>
					</view>
				</view>
			</uni-section>

			<view class='wrapper'>
				<view class='toolbar' @tap="format" style="height: 120px; overflow-y: auto;">
					<view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu" data-name="bold">
					</view>
					<view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti" data-name="italic">
					</view>
					<view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian"
						data-name="underline"></view>
					<view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian"
						data-name="strike"></view>
					<br>
					<!-- #ifndef MP-BAIDU -->
					<view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi"
						data-name="align" data-value="left"></view>
					<!-- #endif -->
					<view :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi"
						data-name="align" data-value="center"></view>
					<view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi"
						data-name="align" data-value="right"></view>
					<view :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi"
						data-name="align" data-value="justify"></view>
					<!-- #ifndef MP-BAIDU -->
					<!-- <view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height"
            data-name="lineHeight" data-value="2"></view>
          <view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing"
            data-name="letterSpacing" data-value="2em"></view>
          <view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju"
            data-name="marginTop" data-value="20px"></view>
          <view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
            data-name="marginBottom" data-value="20px"></view>
          <!-- #endif -->

					<!--          <view class="iconfont icon-clearedformat" @tap="removeFormat"></view> -->

					<!-- #ifndef MP-BAIDU -->
					<!--          <view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font"
              data-name="fontFamily" data-value="Pacifico"></view> -->
					<!-- <view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
              data-name="fontSize" data-value="24px"></view> -->
					<!-- #endif -->
					<!-- <view :class="formats.color === '#0000ff' ? 'ql-active' : ''" class="iconfont icon-text_color"
              data-name="color" data-value="#0000ff"></view>
          <view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
              class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view>
          <view class="iconfont icon-date" @tap="insertDate"></view>
          <view class="iconfont icon--checklist" data-name="list" data-value="check"></view> -->
					<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie"
						data-name="list" data-value="ordered"></view>
					<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
						data-name="list" data-value="bullet"></view>

					<view class="iconfont icon-undo" @tap="undo"></view>
					<view class="iconfont icon-redo" @tap="redo"></view>

					<!-- <view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
          <view class="iconfont icon-indent" data-name="indent" data-value="+1"></view> -->
					<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
					<view class="iconfont icon-charutupian" @tap="insertImage"></view>
					<view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
						data-name="header" :data-value="1"></view>
					<view :class="formats.header === 2 ? 'ql-active' : ''" class="iconfont icon-format-header-2"
						data-name="header" :data-value="2"></view>
					<view :class="formats.header === 3 ? 'ql-active' : ''" class="iconfont icon-format-header-3"
						data-name="header" :data-value="3"></view>
					<!-- <view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
              data-name="script" data-value="sub"></view>
          <view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao"
              data-name="script" data-value="super"></view> -->

					<view class="iconfont icon-shanchu" @tap="clear"></view>

					<!-- <view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl"
              data-name="direction" data-value="rtl"></view> -->
				</view>

				<view class="editor-wrapper">
					<editor id="editor" class="ql-container" placeholder="开始输入..." show-img-size show-img-toolbar
						show-img-resize @statuschange="onStatusChange" :read-only="readOnly" @ready="onEditorReady"
						@blur="blur" @input="writeChange">
					</editor>
					<veiw class="ai" >
						<view class="ai-header" >
							<uni-row>
								<uni-col :span="18">
									<text>以下内容根据输入内容由AI生成:</text>
								</uni-col>
								<uni-col :span="6">
									<uni-row>
										<uni-col :span="12">
											<view class="copy" @click="handleLocked">
												<view class="tooltip" :class="{ active: isLocked }">
												  <text>{{ isLocked ? '锁住' : '解锁' }}</text>
												</view>
												<view>
													<image v-if="!isLocked" class="clipboard" src="../../../static/图钉-空.svg" mode="aspectFit"></image>
													<image v-else class="checkmark" src="../../../static/图钉-面.svg" mode="aspectFit"></image>
												</view>
											</view>
										</uni-col>
										<uni-col :span="12">
											<view class="copy" @click="handleCopy">
												<view class="tooltip" :class="{ active: isCopied }">
												  <text>{{ isCopied ? '复制完成!' : '' }}</text>
												</view>
												<view>
													<image v-if="!isCopied" class="clipboard" src="../../../static/复制.svg" mode="aspectFit"></image>
													<image v-else class="checkmark" src="../../../static/成功.svg" mode="aspectFit"></image>
												</view>
											</view>
										</uni-col>
									</uni-row>
								</uni-col>
							</uni-row>
						</view>
						
						<view class="ai-window">
							<text selectable="true" class="ai-reply">
								{{AIReply}}
							</text>
						</view>
					</veiw>
					<view class="" style="text-align: center; margin-bottom: 80rpx;line-height: 40px;">
						<u-button style="" type="primary" size="medium" @click="pulishArticle">发布</u-button>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		onMounted,
		nextTick,
	} from 'vue';
	//在页面中导入相关api
	import{
		saveArticle,selectArticleCategory,selectArticleTag,articleAddToES
	} from "@/pages/article/api/article.js"
	import { debounce } from 'lodash';
	import { onLoad, onShow } from "@dcloudio/uni-app";
	
	//AI部分变量
	const userWrite = ref('');
	const userWriteChanged = ref('');
	const AIReply = ref('');
	const isLocked = ref(false);
	const isRequest =ref(true);

	//富文本编辑器变量
	const editorCtx = ref(null);
	const readOnly = ref(false);
	const formats = ref({});
	const info = ref('');
	
	//定义分类数组
	const categoryArray = ref([]);
	
	//定义分类选项数组下标
	const index = ref(0);
	
	//定义是否公开变量
	const isPublic = ref('true');
	
	//定义是否为收费变量
	const isCharge = ref('false');
	
	//定义文章标签数组
	const articleTag = ref([]);
	
	//通过LocalStorage获取登录用户信息
	const userDataString = localStorage.getItem("UserId");
	
	//定义响应式变量来存储保存文章信息
	const articleSaveParam = ref({
		userId:'',
		username:'',
		userPhoto:'',
		title:'',
		shortTitle:'',
		articlePhoto:'',
		articleDetail:'',
		articleTag:[],
		categoryId:'',
		isCharge:0,
		isPublic:1,
		source:'',
		sourceUrl:'',
	})
	//定义查询分类对象
	const articleCategoryQueryParam = (null);
	
	const articleTagQueryParam = (null);
	
	//加载页面时调用的方法
	onShow(()=>{
		getArticleCategory();
		const userData = JSON.parse(userDataString);
		articleSaveParam.value.userId = userData.data;
		console.log("当前 访问用户id:"+articleSaveParam.value.userId);
		getArticleTag();
	})
	
	//加载所有分类
	const getArticleCategory =  async ()=>{
		console.log("获取分类");
		const res = await selectArticleCategory(articleCategoryQueryParam);
		for(var i = 0; i < res.data.length; i++){
			console.log(res.data[i].categoryName);
			categoryArray.value[i] = res.data[i].categoryName;
			console.log(categoryArray.value);
		}
		
	}
	//加载所有标签
	const getArticleTag =  async ()=>{
		console.log("获取标签");
		const res = await selectArticleTag(articleTagQueryParam);
		articleTag.value = res.data;
		console.log(articleTag.value);
	}
	
	//定义点击发布事件
	// const pulishArticle = async()=>{
		
	// 	let blobUrl = articleSaveParam.value.articlePhoto;
	// 	// 使用fetch API获取Blob内容
	// 	fetch(blobUrl)
	// 	  .then(response => response.blob()) // 转换为Blob
	// 	  .then(blob => {
	// 	    // 创建一个文件对象
	// 	    const file = new File([blob], 'newFileName.jpg', { type: 'image/jpeg' });
		
	// 	    // 使用uni.uploadFile上传文件
	// 	    uni.uploadFile({
	// 	      url: 'http://localhost:10002/file/upload', // 替换为你的后端接口地址
	// 	      filePath: URL.createObjectURL(file), // 使用createObjectURL生成文件路径
	// 	      name: 'file', // 对应后端接收的参数名
	// 	      formData: {
	// 	        // 可以添加其他表单数据
	// 	        // key: 'value'
	// 	      },
	// 	      success: (res) => {
	// 	        console.log('Upload success:', res.data);
	// 			// 解析后端返回的JSON数据
	// 			const responseData = JSON.parse(res.data);
	// 			// 提取文件路径
	// 			const fileUrl = responseData.data;   
	// 			// 将文件路径赋值给articleSaveParam.value.articlePhoto
	// 			articleSaveParam.value.articlePhoto = fileUrl;
	// 			console.log(articleSaveParam.value.articlePhoto);
	// 	      },
	// 	      fail: (err) => {
	// 	        console.error('Upload error:', err);
	// 	      }
	// 	    });
	// 	  })
	// 	  .catch(error => {
	// 	    console.error('Error:', error);
	// 	  });
		  
	// 	  console.log(articleSaveParam.value);
	// 	  let res = await saveArticle(JSON.stringify(articleSaveParam.value));
	// 	  console.log(res);
	// }
	
	// 定义点击发布事件
	const pulishArticle = async () => {
	  try {
	    // 获取 Blob URL
	    const blobUrl = articleSaveParam.value.articlePhoto;
	
	    // 使用 fetch API 获取 Blob 内容
	    const response = await fetch(blobUrl);
	    const blob = await response.blob();
	
	    // 创建一个文件对象
	    const file = new File([blob], 'newFileName.jpg', { type: 'image/jpeg' });
	
	    // 使用 uni.uploadFile 上传文件
	    const uploadResult = await new Promise((resolve, reject) => {
	      uni.uploadFile({
	        url: 'http://localhost:9091/file/upload', // 替换为你的后端接口地址
	        filePath: URL.createObjectURL(file), // 使用 createObjectURL 生成文件路径
	        name: 'file', // 对应后端接收的参数名
	        formData: {
	          // 可以添加其他表单数据
	          // key: 'value'
	        },
	        success: (res) => {
	          console.log('Upload success:', res.data);
	          resolve(res);
	        },
	        fail: (err) => {
	          console.error('Upload error:', err);
	          reject(err);
	        }
	      });
	    });
	
	    // 解析后端返回的 JSON 数据
	    const responseData = JSON.parse(uploadResult.data);
	
	    // 提取文件路径
	    const fileUrl = responseData.data;
	
	    // 将文件路径赋值给 articleSaveParam.value.articlePhoto
	    articleSaveParam.value.articlePhoto = fileUrl;
	    console.log(articleSaveParam.value.articlePhoto);
	
	    // 打印 articleSaveParam 的当前值
	    console.log(articleSaveParam.value);
	
	    // 调用 saveArticle 方法
	    let res = await saveArticle(JSON.stringify(articleSaveParam.value));
	    console.log(res);
		// 将文章存入ES
		let esRes = await articleAddToES(res.data.id)
		console.log(esRes);
		
		window.location.href = "/#/pages/home/home";
	  } catch (error) {
	    console.error('Error:', error);
	  }
	};
	
	// 定义响应式变量来存储所选文件信息
	// const selectFiles = ref([]);
	
	//定义文章标题改变时的方法
	const articleTitleChange = ()=> {
		console.log(articleSaveParam.value.title);
	}
	
	//定义选择封面图片方法
	const selectPhoto = async (selectFiles)=>{
		console.log(selectFiles.tempFiles[0].path);
		if(selectFiles.tempFiles[0] != null){
			const file = selectFiles.tempFiles[0];
			// const response = await fetch(file.path);
			articleSaveParam.value.articlePhoto = file.path;
			console.log(response);
		}else{
			console.log('No file selected');
		}	
	}
	
	//定义 是否公开选项改变 方法
	const isPublicChange = (e)=>{
		isPublic.value = e.detail.value;
		console.log(isPublic.value);
		articleSaveParam.value.isPublic = isPublic.value;
		if(isPublic.value){
			articleSaveParam.value.isPublic = 1;
		}else {
			articleSaveParam.value.isPublic = 0;
		}
	}

	//定义 是否收费选项改变 方法
	const isChargeChange = (e)=>{
		isCharge.value = e.detail.value;
		console.log(isCharge.value);
		if(isCharge.value){
			articleSaveParam.value.isCharge = 1;
		}else {
			articleSaveParam.value.isCharge = 0;
		}
		
	}
	
	//定义 文章类型改变 方法
	const bindPickerChange = (e) => {
		console.log('picker发送选择改变，携带值为', e.detail.value);
		index.value = e.detail.value;
		articleSaveParam.value.categoryId = index.value + 1;
	};

	//定义 文章标签改变 方法
	const checkboxChange = (e) => {
		const values = e.detail.value;
		console.log("values:" + values);
		for (let i = 0, lenI = articleTag.length; i < lenI; ++i) {
			const item = articleTag[i];
		}
		articleSaveParam.value.articleTag = values;
	}
	
	//
	
	//以下是富文本编辑器方法定义
	const format = (e) => {
		const {
			name,
			value
		} = e.target.dataset;
		if (!name) return;
		editorCtx.value.format(name, value);
	};

	const blur = (e) => {
		info.value = e.detail.html;
		console.log(info.value, e, '失去焦点');
		articleSaveParam.value.articleDetail = info.value;
	};
	
	const writeChange = debounce(async (e) => {
		if(!isLocked.value){
			let askBody = {}
			console.log('文本内容',e.detail.text);
			// 更新编辑器内容
			userWriteChanged.value = e.detail.text;
			if (userWriteChanged.value.trim() != '' && userWriteChanged.value != userWrite.value) {
				userWrite.value=userWriteChanged.value.substring(userWriteChanged.value.length-100);
				console.log(userWrite.value);
				askBody['userInput'] = userWrite.value;
				if(uni.getStorageSync("UserId")){
					askBody['userId'] = uni.getStorageSync("UserId");
				}
				console.log("askBody",askBody);
				
				askAI(askBody);
				
				
			}
		}else{
			console.log("askAI被锁")
		}
	}, 2500); // 2500毫秒内如果没有新的输入，才会执行 writeChange
	
	const askAI = async(askBody) => {
		console.log('能否访问ai',isRequest.value);
		if(isRequest.value){
			AIReply.value = '';
			isRequest.value = false;
			console.log('调用askAI');
			const url = "http://localhost:9091/article/ai";
			const headers = {
				"Content-Type": "application/json",
			};
			if (uni.getStorageSync("VisitToken")) {
				headers['Authorization'] = 'Bearer ' + uni.getStorageSync("VisitToken");
			}
			if (uni.getStorageSync("RefreshToken")) {
				headers['RefreshKey'] = uni.getStorageSync("RefreshToken");
			}
			const data = {
				method: 'POST',
				headers: headers,
				body:JSON.stringify(askBody)
			}
			
			fetch(url,data).then(async response=>{
				if(response.ok){
					console.log('响应',response.body)
					const reader = response.body.getReader();
					console.log('响应',reader)
					const decoder = new TextDecoder('utf-8');
					while(true) {
						const {done, value} = await reader.read();
						if (done) {
						break;
						}
						const chunk = decoder.decode(value, { stream: true });
						console.log(chunk);
						AIReply.value += chunk;
						
					}
					
					isRequest.value = true;
				}
			},(error)=>{
				console.error(error);
			})
			
		}else{
			
			console.log('上一个ai请求还未完成');
		}
	};
		
	// const askAI =  async(askBody) => {
	// 	console.log('调用askAI');
	// 	console.log(askBody);
	// 	const response = await getAIResponse(askBody);
	// 	console.log("response",response);
	// 	console.log("response",response.choices[0].message.content);
	// 	AIReply.value = response.choices[0].message.content;

	// };
	
	// const askAI = (askBody) => {
	// 	console.log('调用askAI');
	// 	const url = "https://spark-api-open.xf-yun.com/v1/chat/completions";
	// 	const headers = {
	// 		"Content-Type": "application/json",
	// 	    "Authorization": "Bearer iZbaDUrFvjAvLLzAbFbY:EbOIrvAoDrrluNDRIPOE" // 注意此处替换自己的APIPassword
	// 	};
	// 	const data = {
	// 	    "model": "generalv3", // 指定请求的AI模型是pro
	// 		"max_tokens": 500,
	// 	    "messages": [
	// 			{
	// 			    "role": "system",
	// 			    "content": "你是一名资深程序员请根据提供内容，续写一篇编程博客的内容，要求内容详细、步骤清晰，语言通俗易懂，适合不同水平的读者，请提供必要的代码示例和解释，确保文章的实用性和可读性。"
	// 			},{
	// 	            "role": "user",
	// 	            "content": askBody
	// 	        }
	// 	    ],
	// 	    "stream": true
	// 	};
		
	// 	return new Promise((resolve, reject) => {
			
	// 		const requstAI = uni.request({
	// 			url: url,
	// 			method: 'POST',
	// 			header: headers,
	// 			data: data,
	// 			responseType: "text",
	// 			enableChunked: true,
	// 			success: (response) => {
	// 				console.log('requestAI成功,返回response',response)
	// 				resolve(response)
	// 			},
	// 			fail: (error) => {
	// 				console.error('requstAI失败:', error);
	// 				reject(error)
	// 			},
	// 			complete: () => {
	// 				if (requstAI.onComplete) {
	// 					requstAI.onComplete();
	// 				}
	// 			}
	// 		});
			
	// 		resolve(requstAI);
	// 	});
	// };
	
	const handleLocked = () => {
		isLocked.value=!isLocked.value;
	};
	
	// 定义响应式变量
	const isCopied = ref(false);
	// 定义处理复制的方法
	const handleCopy = () => {
	  if( AIReply.value.trim() != ""){// 使用uni.setClipboardData方法来复制文本
		  uni.setClipboardData({
			data: AIReply.value,
			success: () => {
			  // 复制成功后的回调函数
			  isCopied.value = true; // 设置 isCopied 为 true，表示已复制
			  setTimeout(() => {
				isCopied.value = false; // 1.5秒后重置 isCopied 为 false
			  }, 1500); // 1.5秒后重置状态
			}
		  });
	  }
	};

	const readOnlyChange = () => {
		readOnly.value = !readOnly.value;
	};

	const onEditorReady = () => {
		if (process.env.UNI_PLATFORM === 'mp-baidu') {
			editorCtx.value = requireDynamicLib('editorLib').createEditorContext('editor');
		} else {
			const query = uni.createSelectorQuery().select('#editor').context((res) => {
				editorCtx.value = res.context;
			});
			query.exec();
		}
	};

	const undo = () => {
		editorCtx.value.undo();
	};

	const redo = () => {
		editorCtx.value.redo();
	};

	const onStatusChange = (e) => {
		const formats = e.detail;
		formats.value = formats;
	};

	const insertDivider = () => {
		editorCtx.value.insertDivider({
			success: () => {
				console.log('insert divider success');
			},
		});
	};

	const clear = () => {
		uni.showModal({
			title: '清空编辑器',
			content: '确定清空编辑器全部内容？',
			success: (res) => {
				if (res.confirm) {
					editorCtx.value.clear({
						success: () => {
							console.log('clear success');
						},
					});
				}
			},
		});
	};

	const removeFormat = () => {
		editorCtx.value.removeFormat();
	};

	const insertDate = () => {
		const date = new Date();
		const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
		editorCtx.value.insertText({
			text: formatDate,
		});
	};

	const insertImage = () => {
		uni.chooseImage({
			count: 1,
			success: (res) => {
				editorCtx.value.insertImage({
					src: res.tempFilePaths[0],
					alt: '图像',
					success: () => {
						console.log('insert image success');
					},
				});
			},
		});
	};

	onMounted(() => {
		onEditorReady();
	});
</script>

<style>
	@import "./editor-icon.css";
	/* @import "../../static/editor/assets/editor.css" */

	.setting-list{
		padding: 26rpx;
	}
	
	.setting-item{
		padding-bottom: 10px;
	}
	
	.setting-switch{
		display: inline-block;
		margin-right: 60vw;
	}

	.tag-list {
		justify-content: flex-start;
		padding: 26rpx;
	}

	.tag-list-item {
		padding: 0px 0px 10px 0px;
	}

	.input-article-photo {
		padding: 26rpx;
	}

	.input-article-title {
		padding: 26rpx;
	}

	.input-article-category {
		padding: 26rpx;
	}

	.page-body {
		height: calc(100vh - var(--window-top) - var(--status-bar-height));
	}

	.wrapper {
		height: 100%;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
	}

	.editor-wrapper {
		height: calc(100vh - var(--window-top) - var(--status-bar-height) - 140px);
		background: #fff;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
	}

	.iconfont {
		display: inline-block;
		padding: 26rpx 26rpx;
		width: 80rpx;
		height: 80rpx;
		cursor: pointer;
		font-size: 20px;
	}

	.toolbar {
		box-sizing: border-box;
		border-bottom: 0;
		font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
	}

	.ql-container {
		flex: 1;
		box-sizing: border-box;
		padding: 12px 15px;
		width: 100%;
		min-height: 30vh;
		margin-top: 20px;
		font-size: 16px;
		line-height: 1.5;
	}

	.ql-active {
		color: #06c;
	}
	
	.ai{
		width: 100%;
		background-color: #fff;
		border: 1px solid #ccc;
		border-radius: 5px;
		box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
	}
	
	.ai-header{
		width: 100%;
		background-color: #007aff;
		color: #fff;
		padding: 10px;
		font-size: 18px;
		border-top-left-radius: 5px;
		border-top-right-radius: 5px;
	}
	
	.ai-window {
		height: 200px;
		overflow-y: scroll;
	}
	
	.ai-reply {
		
		display: block;
		padding: 10px;
	}
	
	
	.copy {
	  box-sizing: border-box;
	  width: var(--button-diameter, 36px);
	  height: var(--button-diameter, 36px);
	  border-radius: var(--button-border-radius, 10px);
	  background-color: var(--button-bg, #007aff);
	  color: var(--button-text-color, #CCCCCC);
	  border: none;
	  cursor: pointer;
	  position: relative;
	  outline: none;
	}
	
	.copy:hover,
	.copy:focus {
	  background-color: var(--button-hover-bg, #007aff);
	}
	
	.copy:active {
	  outline: var(--button-outline-width, 1px) solid var(--button-outline-color, rgb(141, 141, 141));
	}
	
	.tooltip {
	  position: absolute;
	  opacity: 0;
	  visibility: hidden;
	  top: 0;
	  left: 50%;
	  transform: translateX(-50%);
	  white-space: nowrap;
	  font: var(--tooltip-font-size, 12px) var(--tooltip-font-family, Menlo, Roboto Mono, monospace);
	  color: var(--tootip-text-color, rgb(50, 50, 50));
	  background: var(--tooltip-bg, #f4f3f3);
	  padding: var(--tooltip-padding-y, 7px) var(--tooltip-padding-x, 7px);
	  border-radius: var(--toolptip-border-radius, 4px);
	  pointer-events: none;
	  transition: all var(--tooltip-transition-duration, 0.3s) cubic-bezier(0.68, -0.55, 0.265, 1.55);
	}
	
	.tooltip.active {
	  opacity: 1;
	  visibility: visible;
	  top: calc((100% + var(--tooltip-offset, 8px)) * -1);
	}
	
	.copy image {
	  position: absolute;
	  top: 50%;
	  left: 50%;
	  transform: translate(-50%, -50%);
	  width: 18px; /* 根据你的SVG文件大小调整 */
	  height: 18px; /* 根据你的SVG文件大小调整 */
	}
	
</style>